<template>
  <div class="page-container">
    <el-form
      ref="dataForm"
      label-width="110px"
      :model="formData"
      class="fit-box full-height"
      :rules="rules"
    >
      <el-row style="margin-top: 10px;">
        <el-col :span="6">
          <el-form-item label="组件名称" prop="name">
            <el-input v-model="formData.name" />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="组件类型" prop="type">
            <ac-buttons v-model="formData.type" options="表格,表单,页面" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '页面'">
          <el-form-item label="页面名称" prop="dataPageId">
            <ac-tree
              v-model="formData.dataPageId"
              data-url="/system/page/queryTree"
              typeSelect="page"
              @change="changeDataModel"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '表格' || formData.type === '表单'">
          <el-form-item label="数据源类型" prop="dataType">
            <ac-buttons v-model="formData.dataType" options="数据模型" options1="数据模型,数据集" />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="是否显示" prop="showComp">
            <ac-dict-switch v-model="formData.showComp" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="高度自适应" prop="autoHeight">
            <ac-dict-switch v-model="formData.autoHeight" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="(formData.type === '表格' || formData.type === '表单') && formData.dataType === '数据模型'">
          <el-form-item label="数据模型" prop="dataModelId">
            <ac-tree
              v-model="formData.dataModelId"
              data-url="/system/dataModel/queryTree"
              typeSelect="model"
              @change="changeDataModel"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.dataType === '数据集'">
          <el-form-item label="数据集" prop="datasetId">
            <ac-tree
              v-model="formData.datasetId"
              data-url="/system/dataset/queryTree"
              typeSelect="model"
              @change="changeDataset"
            />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '表格' && formData.dataType">
          <el-form-item label="表格名称" prop="dataTableId">
            <ac-select v-model="formData.dataTableId" :options="dataTableOptions" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="(formData.type === '表格' || formData.type === '表单') && formData.dataType">
          <el-form-item label="表单名称" prop="dataFormId">
            <ac-select v-model="formData.dataFormId" :options="dataFormOptions" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '表格'">
          <el-form-item label="显示树控件" prop="showTree">
            <ac-dict-switch v-model="formData.showTree" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '表格' && formData.showTree === '1'">
          <el-form-item label="树控件名称" prop="showTree">
            <el-input v-model="formData.treeName" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '表格' && formData.showTree === '1'">
          <el-form-item label="树控件宽度" prop="treeWidth">
            <ac-number v-model="formData.treeWidth" :point="0" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '表格'">
          <el-form-item label="显示自动刷新" prop="showRefresh">
            <ac-dict-switch v-model="formData.showRefresh" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col :span="6" v-if="formData.type === '表格'">
          <el-form-item label="翻页保持选中" prop="pageSelected">
            <ac-dict-switch v-model="formData.pageSelected" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-if="formData.type === '表格' && formData.showTree === '1'">
        <el-col :span="24">
          <el-row style="margin-bottom: 8px;">
            <el-col :span="24"><span class="section-tips">树控件设置</span></el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item label="数据模型" prop="treeDataModelId">
                <ac-tree
                  v-model="formData.treeDataModelId"
                  data-url="/system/dataModel/queryTree"
                  typeSelect="model"
                  @change="changeTreeDataModel"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="节点字段" prop="treeNodeFieldId">
                <ac-select v-model="formData.treeNodeFieldId" :options="treeDataFieldOptions" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="父节点字段" prop="treeParentFieldId">
                <ac-select v-model="formData.treeParentFieldId" :options="treeDataFieldOptions" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item label="显示字段" prop="treeShowFieldId">
                <ac-select v-model="formData.treeShowFieldId" :options="treeDataFieldOptions" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="排序字段" prop="treeOrdinalFieldId">
                <ac-select v-model="formData.treeOrdinalFieldId" :options="treeDataFieldOptions" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="操作表单" prop="treeFormId">
                <template #label>
                  <span style="margin-right: 5px">操作表单</span>
                  <el-tooltip content="为空时，树节点上无操作功能。不为空时，可以在树节点上通过此表单操作树节点内容">
                    <ac-icon iconId="018dca8ec9890493be26" />
                  </el-tooltip>
                </template>
                <ac-select v-model="formData.treeFormId" :options="treeDataFormOptions" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="formData.treeFormId">
            <el-col :span="8">
              <el-form-item label="新增脚本" prop="treeAddScriptId">
                <ac-tree
                  v-model="formData.treeAddScriptId"
                  data-url="/system/scriptGroovy/queryTree"
                  type-select="script"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="编辑脚本" prop="treeEditScriptId">
                <ac-tree
                  v-model="formData.treeEditScriptId"
                  data-url="/system/scriptGroovy/queryTree"
                  type-select="script"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="删除脚本" prop="treeDeleteScriptId">
                <ac-tree
                  v-model="formData.treeDeleteScriptId"
                  data-url="/system/scriptGroovy/queryTree"
                  type-select="script"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="8">
              <el-form-item label="关系映射" prop="treeMappingType">
                <ac-buttons v-model="formData.treeMappingType" options="一对多,多对多" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="出参字段" prop="treeOutputFieldId">
                <ac-select v-model="formData.treeOutputFieldId" :options="treeDataFieldOptions" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="数据过滤字段" prop="filterFieldId">
                <ac-select v-model="formData.filterFieldId" :options="dataFieldOptions" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="formData.treeMappingType === '多对多'">
            <el-col :span="8">
              <el-form-item label="中间模型" prop="middleModelId">
                <ac-tree
                  v-model="formData.middleModelId"
                  data-url="/system/dataModel/queryTree"
                  typeSelect="model"
                  @change="changeMiddleDataModel"
                />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="入参字段" prop="middleInputFieldId">
                <ac-select v-model="formData.middleInputFieldId" :options="middleFieldOptions" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="出参字段" prop="middleOutputFieldId">
                <ac-select v-model="formData.middleOutputFieldId" :options="middleFieldOptions" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="formData.treeMappingType === '一对多'">
            <el-col :span="8">
              <el-form-item label="开启递归查询" prop="recursiveQuery">
                <ac-dict-switch v-model="formData.recursiveQuery" dictCode="dictYesNo" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row style="margin-bottom: 15px;">
            <el-col :span="24">
              <el-button
                type="success"
                @click="addPrivilege"
              >添加权限组</el-button>
            </el-col>
          </el-row>
          <el-row
            v-for="(privilege, privilegeIndex) in formData.privilegeList || []"
            style="margin-bottom: 15px;"
            :key="privilege.id || privilege.rowFlag"
          >
            <el-col :span="24">
              <el-row>
                <el-col :span="6">
                  <el-form-item label="角色" prop="imageStyle">
                    <ac-role-select showAll v-model="privilege.roleId" />
                  </el-form-item>
                </el-col>
                <el-col :span="6">
                  <el-form-item label="排序" prop="ordinal">
                    <ac-number v-model="privilege.ordinal" :point="0" />
                  </el-form-item>
                </el-col>
                <el-col :span="12" style="text-align: right;align-content: center">
                  <el-button
                    v-if="(!sortableInst || sortingId !== (privilege.id || privilege.rowFlag))
                      && (privilege.conditionList || []).length > 1"
                    type="primary"
                    @click="sortPrivilegeField(privilege)"
                  >开启排序</el-button>
                  <el-button
                    v-if="sortableInst && sortingId === (privilege.id || privilege.rowFlag)"
                    type="info"
                    @click="unSortPrivilegeField"
                  >关闭排序</el-button>
                  <el-button
                    type="success"
                    @click="addPrivilegeCondition(privilege)"
                  >添加过滤条件</el-button>
                  <el-button
                    type="danger"
                    @click="deletePrivilege(privilege)"
                  >删除权限组</el-button>
                </el-col>
              </el-row>
              <el-table
                :show-overflow-tooltip="false"
                tooltip-effect="light"
                class="field-table edit-table"
                width="100%"
                :ref="el => setRefs(el, privilege)"
                :row-key="getPrivilegeRowKey"
                :data="privilege.conditionList"
                :border="true"
                :stripe="false"
              >
                <el-table-column
                  header-align="center"
                  label="拼接方式"
                  :min-width="120"
                  prop="connectSymbol"
                >
                  <template #default="scope">
                    <el-form-item
                      label-width="0"
                      :prop="scope.$index === 0 ? null : ('privilegeList.' + privilegeIndex + '.conditionList.' + scope.$index +'.connectSymbol')"
                      :rules="[{required: true, message: '拼接方式不能为空！', trigger: ['change', 'blur']}]"
                    >
                      <ac-select v-model="scope.row.connectSymbol" options="and,or"/>
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column
                  header-align="center"
                  label="前置括号"
                  :min-width="120"
                  prop="frontBracket"
                >
                  <template #default="scope">
                    <ac-select v-model="scope.row.frontBracket" options="(,((,(((,((((" />
                  </template>
                </el-table-column>
                <el-table-column
                  header-align="center"
                  label="过滤字段"
                  :min-width="120"
                  prop="fieldId"
                >
                  <template #default="scope">
                    <el-form-item
                      label-width="0"
                      :prop="'privilegeList.' + privilegeIndex + '.conditionList.' + scope.$index +'.fieldId'"
                      :rules="[{required: true, message: '过滤字段不能为空！', trigger: ['change', 'blur']}]"
                    >
                      <ac-select v-model="scope.row.fieldId" :options="treeDataFieldOptions" />
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column
                  header-align="center"
                  label="比较符"
                  :min-width="120"
                  prop="compareSymbol"
                >
                  <template #default="scope">
                    <el-form-item
                      label-width="0"
                      :prop="'privilegeList.' + privilegeIndex + '.conditionList.' + scope.$index +'.compareSymbol'"
                      :rules="[{required: true, message: '比较符不能为空！', trigger: ['change', 'blur']}]"
                    >
                      <ac-select
                        v-model="scope.row.compareSymbol"
                        options="大于,大于等于,等于,小于,小于等于,不等于,模糊"
                      />
                    </el-form-item>
                  </template>
                </el-table-column>
                <el-table-column
                  header-align="center"
                  label="比较值"
                  :min-width="120"
                  prop="compareValue"
                >
                  <template #header>
                    <span style="margin-right: 5px">默认值</span>
                    <ac-default-value-tips />
                  </template>
                  <template #default="scope">
                    <ac-tree
                      v-if="scope.row.compareSymbol === 'script'"
                      v-model="scope.row.compareValue"
                      data-url="/system/scriptGroovy/queryTree"
                      type-select="script"
                    />
                    <ac-input
                      v-else-if="scope.row.compareSymbol !== 'script' && scope.row.manually === '1'"
                      v-model="scope.row.compareValue"
                    />
                    <component
                      v-else-if="scope.row.compareSymbol !== 'script' && scope.row.fieldId"
                      v-model="scope.row.compareValue"
                      :is="getComponent(scope.row.fieldId) || 'ac-input'"
                      v-bind="getOptions(scope.row.fieldId)"
                    />
                    <el-input v-else v-model="scope.row.compareValue" />
                    <ac-dict-switch
                      v-if="scope.row.compareSymbol !== 'script'"
                      v-model="scope.row.manually"
                      dictCode="dictYesNo"
                      style="margin: 0 5px;"
                      title="手动录入"
                    />
                  </template>
                </el-table-column>
                <el-table-column
                  header-align="center"
                  label="后置括号"
                  :min-width="120"
                  prop="behindBracket"
                >
                  <template #default="scope">
                    <ac-select v-model="scope.row.behindBracket" options="),)),))),))))" />
                  </template>
                </el-table-column>
                <el-table-column
                  header-align="center"
                  align="center"
                  label="操作"
                  :min-width="80"
                  prop="ordinal"
                >
                  <template #default="scope">
                    <el-button
                      type="danger"
                      @click="deletePrivilegeCondition(privilege, scope.row)"
                      link
                    >删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-col>
          </el-row>
        </el-col>
      </el-row>
      <el-row v-if="formData.type === '表格'">
        <el-col :span="24">
          <el-row style="margin-bottom: 8px;">
            <el-col :span="24"><span class="section-tips">查询设置</span></el-col>
          </el-row>
          <el-row>
            <el-col :span="6">
              <el-form-item label="开启高级查询" prop="advanceQuery">
                <ac-dict-switch v-model="formData.advanceQuery" dictCode="dictYesNo" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item>
                <template #label>
                  <span style="margin-right: 5px">查询条件</span>
                  <el-tooltip content="开启排序后可拖动排序">
                    <ac-icon iconId="018dca8ec9890493be26" />
                  </el-tooltip>
                </template>
                <div
                  ref="sortFilterRadioGroup"
                  :class="['sort-box', sortableFilterInst ? 'pointer' : '']"
                >
                  <div
                    class="sort-item"
                    v-for="filter in formData.filterList || []"
                    :key="filter.rowFlag"
                  >
                    <span>{{filter.name}}</span>
                    <ac-icon
                      iconId="018dca6db20c6a3aaf68"
                      color="#409EFF"
                      @click.stop="editFilter(filter)"
                    />
                    <ac-icon
                      iconId="018dca412c4ebd53fd1d"
                      color="red"
                      @click.prevent="deleteFilter(filter)"
                    />
                  </div>
                  <el-button
                    @click="editFilter(null)"
                    type="success"
                  >添加查询</el-button>
                  <el-button
                    v-if="!sortableFilterInst && (formData.filterList || []).length > 1"
                    @click="sortFilterList"
                    type="primary"
                  >开启排序</el-button>
                  <el-button
                    v-if="sortableFilterInst"
                    @click="closeFilterList"
                    type="info"
                  >关闭排序</el-button>
                </div>
              </el-form-item>
            </el-col>
          </el-row>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-row style="margin-bottom: 8px;">
            <el-col :span="24"><span class="section-tips">按钮设置</span></el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="按钮换行">
                <ac-dict-switch v-model="formData.buttonWrap" dictCode="dictYesNo" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-if="
            buttonList.filter(item =>
                formData.type === '表格' ? item.type === '表格按钮' || item.type === '通用按钮'
                  : formData.type === '表单' ? item.type === '表单按钮' || item.type === '通用按钮'
                    : item.type === '通用按钮').length > 0"
          >
            <el-col :span="24">
              <el-form-item label="内置按钮">
                <el-checkbox-group v-model="selectButtonIds" @change="changeSelectButton">
                  <el-checkbox-button
                    v-for="button in buttonList.filter(item =>
                      formData.type === '表格' ? item.type === '表格按钮' || item.type === '通用按钮'
                        : formData.type === '表单' ? item.type === '表单按钮' || item.type === '通用按钮'
                          : item.type === '通用按钮')"
                    :key="button.id"
                    :value="button.id"
                  >{{ button.name }}</el-checkbox-button>
                </el-checkbox-group>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item>
                <template #label>
                  <span style="margin-right: 5px">已选按钮</span>
                  <el-tooltip content="开启排序后可拖动排序">
                    <ac-icon iconId="018dca8ec9890493be26" />
                  </el-tooltip>
                </template>
                <div
                  ref="sortRadioGroup"
                  :class="['sort-box', sortableInst ? 'pointer' : '']"
                >
                  <div
                    class="sort-item"
                    v-for="button in formData.buttonList || []"
                    :key="button.rowFlag"
                  >
                    <span>{{button.name}}</span>
                    <ac-icon
                      v-if="!button.buttonId || (button.buttonId && '新增,编辑,复制,明细,删除,批量编辑'.indexOf(button.name) >= 0)"
                      iconId="018dca6db20c6a3aaf68"
                      color="#409EFF"
                      @click.stop="editButton(button)"
                    />
                    <ac-icon
                      iconId="018dca412c4ebd53fd1d"
                      color="red"
                      @click.prevent="deleteSelectedButton(button)"
                    />
                  </div>
                  <el-button
                    @click="editButton(null)"
                    type="success"
                  >添加按钮</el-button>
                  <el-button
                    v-if="!sortableInst && (formData.buttonList || []).length > 1"
                    @click="sortButtonList"
                    type="primary"
                  >开启排序</el-button>
                  <el-button
                    v-if="sortableInst"
                    @click="closeButtonList"
                    type="info"
                  >关闭排序</el-button>
                </div>
              </el-form-item>
            </el-col>
          </el-row>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-row>
            <el-col :span="12"><span class="section-tips">参数配置</span></el-col>
            <el-col :span="12" style="text-align: right">
              <el-button
                v-if="!sortParamIndexInst && (formData.paramList || []).length > 1"
                type="primary"
                @click="sortParamIndex"
              >开启排序</el-button>
              <el-button
                v-if="sortParamIndexInst"
                type="info"
                @click="unSortParamIndex"
              >关闭排序</el-button>
              <el-button
                type="success"
                @click="addCompParam"
              >添加参数</el-button>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-row>
                <el-col :span="24" style="padding: 5px 0 10px 0">
                  <el-table
                    ref="sortParamTable"
                    :show-overflow-tooltip="false"
                    tooltip-effect="light"
                    width="100%"
                    class="edit-table"
                    :data="formData.paramList"
                    :row-key="getParamRowKey"
                    :border="true"
                    :stripe="false"
                  >
                    <el-table-column
                      header-align="center"
                      label="参数类型"
                      min-width="100"
                    >
                      <template #default="scope">
                        <ac-select v-model="scope.row.type" options="入参,出参" />
                      </template>
                    </el-table-column>
                    <el-table-column
                      header-align="center"
                      label="页面参数"
                      :min-width="120"
                    >
                      <template #default="scope">
                        <ac-select
                          v-model="scope.row.pageParamId"
                          :options="currPageParamList.map(param => ({'key': param.id, 'value': param.name}))"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column
                      header-align="center"
                      label="应用类型"
                      :min-width="120"
                    >
                      <template #default="scope">
                        <ac-select
                          v-model="scope.row.useType"
                          options="表格,表单,页面,全部"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column
                      header-align="center"
                      label="匹配方式"
                      :min-width="120"
                    >
                      <template #default="scope">
                        <ac-select
                          v-model="scope.row.matchMode"
                          options="大于,大于等于,等于,小于,小于等于,不等于,模糊"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column
                      header-align="center"
                      label="组件参数"
                      :min-width="120"
                    >
                      <template #default="scope">
                        <ac-select
                          v-model="scope.row.pageCompParamId"
                          :options="compParamOptions"
                        />
                      </template>
                    </el-table-column>
                    <el-table-column
                      header-align="center"
                      align="center"
                      label="操作"
                      width="80"
                      prop="width"
                    >
                      <template #default="scope">
                        <el-button
                          type="danger"
                          @click="deleteCompParam(scope.row)"
                          link
                        >删除</el-button>
                      </template>
                    </el-table-column>
                  </el-table>
                </el-col>
              </el-row>
            </el-col>
          </el-row>
        </el-col>
      </el-row>
    </el-form>
  </div>

  <!--按钮编辑-->
  <el-dialog
    v-model="buttonVisible"
    width="950px"
    :title="buttonTitle"
    :close-on-click-modal="false"
    destroy-on-close
    append-to-body
    draggable
    fullscreen
  >
    <el-form
      ref="buttonForm"
      label-width="130px"
      label-position="right"
      :model="buttonData"
      :rules="buttonRules"
    >
      <el-row v-if="buttonData.buttonId">
        <el-col :span="8">
          <el-form-item label="全屏弹窗">
            <ac-dict-switch v-model="buttonData.dialogFullscreen" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col :span="8" v-if="buttonData.dialogFullscreen === '0'">
          <el-form-item label="弹窗大小">
            <ac-input v-model="buttonData.dialogWidth" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="显示位置">
            <ac-checkbox v-model="buttonData.showPosition" options="顶部,行内,底部,表单" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-if="!buttonData.buttonId">
        <el-col :span="8">
          <el-form-item label="名称" prop="name">
            <el-input v-model="buttonData.name" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="类型" prop="type">
            <ac-select
              v-model="buttonData.type"
              options="新增,编辑,删除,上传,下载,打印,提交数据,下载模板,弹出页面,批量编辑,调用脚本"
              @change="changeType"
            />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="数据数量">
            <ac-buttons v-model="buttonData.dataVolume" options="不限,单条,多条" />
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="显示位置">
            <ac-checkbox v-model="buttonData.showPosition" options="顶部,行内,底部,表单" />
          </el-form-item>
        </el-col>
        <el-col :span="8" v-if="'新增,编辑,弹出页面,批量编辑'.indexOf(buttonData.type) >= 0">
          <el-form-item label="全屏弹窗">
            <ac-dict-switch v-model="buttonData.dialogFullscreen" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col
          v-if="buttonData.dialogFullscreen === '0' && '新增,编辑,弹出页面,批量编辑'.indexOf(buttonData.type) >= 0"
          :span="8"
        >
          <el-form-item label="弹窗大小">
            <ac-input v-model="buttonData.dialogWidth" />
          </el-form-item>
        </el-col>
        <el-col
          v-if="'新增,编辑,批量编辑'.indexOf(buttonData.type) >= 0 && (buttonData.dialogPageId || '') === ''"
          :span="8"
        >
          <el-form-item label="弹窗表单">
            <ac-tree
              v-model="buttonData.dialogFormId"
              data-url="/system/dataForm/queryTree"
              typeSelect="form"
            />
          </el-form-item>
        </el-col>
        <el-col
          v-if="'新增,编辑,弹出页面,批量编辑'.indexOf(buttonData.type) >= 0 && (buttonData.dialogFormId || '') === ''"
          :span="8"
        >
          <el-form-item label="弹窗页面">
            <ac-tree
              v-model="buttonData.dialogPageId"
              data-url="/system/page/queryTree"
              typeSelect="page"
              @change="changePage"
            />
          </el-form-item>
        </el-col>
        <el-col
          v-if="'新增,编辑,批量编辑'.indexOf(buttonData.type) >= 0"
          :span="8"
        >
          <el-form-item label="保存后执行脚本">
            <ac-dict-switch v-model="buttonData.saveAndRun" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col
          v-if="'新增,编辑,弹出页面'.indexOf(buttonData.type) >= 0 && buttonData.dialogPageId"
          :span="24"
        >
          <el-form-item
            v-if="buttonData.paramList && buttonData.paramList.length > 0"
            label="出参配置"
            prop="pageId"
          >
            <div style="display: flex;flex-direction: column">
              <div
                class="param-item"
                v-for="(param, index) in buttonData.paramList"
                :key="index"
              >
                <div class="param-field">
                  <ac-select
                    v-model="param.fieldName"
                    :options="dataFieldNameOptions"
                  />
                </div>
                <div class="param-split"><ac-icon iconId="018eecae20bd010c2adf" /></div>
                <div class="param-page">
                  <el-input v-model="param.pageParamName" disabled />
                </div>
              </div>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="8" v-if="'新增,编辑,提交数据,批量编辑,调用脚本'.indexOf(buttonData.type) >= 0">
          <el-form-item label="提交校验">
            <ac-dict-switch v-model="buttonData.submitValidate" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col :span="8" v-if="'上传,下载,下载模板'.indexOf(buttonData.type) < 0">
          <el-form-item label="提交确认语">
            <el-input v-model="buttonData.submitPrompt" />
          </el-form-item>
        </el-col>
        <el-col :span="8" v-if="!buttonData.buttonId
            && '上传,下载,提交数据,下载模板'.indexOf(buttonData.type) < 0
            && '新增,编辑,批量编辑,调用脚本'.indexOf(buttonData.type) >= 0"
        >
          <el-form-item label="提交执行脚本">
            <template #label>
              <span style="margin-right: 5px">提交执行脚本</span>
              <el-tooltip>
                <template #content>
                  <div>脚本接收参数：</div>
                  <div>1、dataList: 表格勾选的数据。</div>
                  <div>2、当为上传时，importList: 导入的excel数据</div>
                </template>
                <ac-icon iconId="018dca8ec9890493be26" />
              </el-tooltip>
            </template>
            <ac-tree
              v-model="buttonData.executeScriptId"
              data-url="/system/scriptGroovy/queryTree"
              type-select="script"
            />
          </el-form-item>
        </el-col>
        <el-col
          v-if="!buttonData.buttonId
            && '上传,下载,提交数据,下载模板'.indexOf(buttonData.type) < 0
            && '新增,编辑,批量编辑,调用脚本'.indexOf(buttonData.type) >= 0"
          :span="8"
        >
          <el-form-item label="显示执行结果">
            <ac-dict-switch v-model="buttonData.showExecuteResult" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col
          v-if="!buttonData.buttonId
            && '弹出页面,调用脚本'.indexOf(buttonData.type) >= 0"
          :span="8"
        >
          <el-form-item :label="buttonData.type === '弹出页面' ? '关闭时刷新' : '执行后刷新'">
            <ac-dict-switch v-model="buttonData.endRefresh" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col
          v-if="!buttonData.buttonId && buttonData.type === '弹出页面'"
          :span="8"
        >
          <el-form-item label="显示关闭按钮">
            <ac-dict-switch v-model="buttonData.showCloseButton" dictCode="dictYesNo" />
          </el-form-item>
        </el-col>
        <el-col
          v-if="!buttonData.buttonId && buttonData.showPosition.indexOf('表单') >= 0"
          :span="8"
        >
          <el-form-item label="绑定按钮名称">
            <ac-input v-model="buttonData.bindButton" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row v-if="!buttonData.buttonId">
        <el-col :span="5">
          <el-form-item label="按钮图标">
            <ac-icon-select v-model="buttonData.iconId" iconSize="22" />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="字体颜色">
            <el-color-picker
              v-model="buttonData.fontColor"
              show-alpha
              :predefine="predefineColors"
              color-format="hex"
            />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="背景颜色">
            <el-color-picker
              v-model="buttonData.backgroundColor"
              show-alpha
              :predefine="predefineColors"
              color-format="hex"
            />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="边框颜色">
            <el-color-picker
              v-model="buttonData.borderColor"
              show-alpha
              :predefine="predefineColors"
              color-format="hex"
            />
          </el-form-item>
        </el-col>
      </el-row>
      <div
        v-if="buttonData.type === '新增'
          || buttonData.type === '编辑'
          || buttonData.type === '提交数据'
          || buttonData.type === '批量编辑'"
        style="padding-left: 70px;"
      >
        <el-row>
          <el-col :span="24" style="margin-bottom: 5px;">
            <el-button
              type="success"
              @click="addUpdate"
            >添加默认值</el-button>
          </el-col>
        </el-row>
        <el-table
          :show-overflow-tooltip="false"
          tooltip-effect="light"
          class="field-table edit-table"
          style="margin-bottom: 20px"
          width="100%"
          :data="buttonData.updateList"
          :border="true"
          :stripe="false"
        >
          <el-table-column
            header-align="center"
            label="字段"
            :min-width="120"
            prop="fieldId"
          >
            <template #default="scope">
              <ac-select v-model="scope.row.fieldId" :options="dataFieldOptions" />
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            align="center"
            label="默认值"
            :min-width="120"
            prop="value"
          >
            <template #header>
              <span style="margin-right: 5px">默认值</span>
              <ac-default-value-tips />
            </template>
            <template #default="scope">
              <ac-input
                v-if="scope.row.manually === '1' || !scope.row.fieldId"
                v-model="scope.row.fieldValue"
              />
              <component
                v-else-if="scope.row.fieldId"
                v-model="scope.row.fieldValue"
                :is="getComponent(scope.row.fieldId)"
                v-bind="getOptions(scope.row.fieldId)"
              />
              <ac-dict-switch
                v-model="scope.row.manually"
                dictCode="dictYesNo"
                style="margin: 0 5px;"
                title="手动录入"
              />
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            align="center"
            label="操作"
            :width="80"
            prop="ordinal"
          >
            <template #default="scope">
              <el-button
                type="danger"
                @click="deleteUpdate(scope.row)"
                link
              >删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div style="padding-left: 70px;">
        <el-row>
          <el-col :span="24" style="margin-bottom: 5px;">
            <el-button
              type="success"
              @click="addCondition"
            >添加显示条件</el-button>
          </el-col>
        </el-row>
        <el-table
          :show-overflow-tooltip="false"
          tooltip-effect="light"
          class="field-table edit-table"
          style="margin-bottom: 20px"
          width="100%"
          :data="buttonData.conditionList"
          :border="true"
          :stripe="false"
        >
          <el-table-column
            header-align="center"
            label="显示分组"
            :min-width="120"
            prop="grouping"
          >
            <template #header>
              <span style="margin-right: 5px">显示分组</span>
              <el-tooltip content="同一分组为 and 条件，不同分组间为 or 条件">
                <ac-icon iconId="018dca8ec9890493be26" />
              </el-tooltip>
            </template>
            <template #default="scope">
              <ac-number v-model="scope.row.grouping" :point="0" />
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            label="条件字段"
            :min-width="120"
            prop="fieldId"
          >
            <template #default="scope">
              <ac-select v-model="scope.row.fieldId" :options="dataFieldOptions" />
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            label="条件类型"
            :min-width="120"
            prop="type"
          >
            <template #default="scope">
              <ac-select v-model="scope.row.type" options="等于,不等于,包含,不包含" />
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            align="center"
            label="条件值"
            :min-width="120"
            prop="value"
          >
            <template #header>
              <span style="margin-right: 5px">默认值</span>
              <ac-default-value-tips />
            </template>
            <template #default="scope">
              <component
                v-if="scope.row.fieldId"
                v-model="scope.row.value"
                :is="getCondComponent(scope.row.fieldId) || 'ac-input'"
                v-bind="getOptions(scope.row.fieldId)"
              />
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            align="center"
            label="操作"
            :width="80"
            prop="ordinal"
          >
            <template #default="scope">
              <el-button
                type="danger"
                @click="deleteCondition(scope.row)"
                link
              >删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div
        v-if="!buttonData.buttonId
          && (buttonData.type === '上传' || buttonData.type === '下载' || buttonData.type === '下载模板')"
        style="padding-left: 70px;"
      >
        <el-row>
          <el-col :span="5" v-if="buttonData.type === '上传'">
            <el-form-item label="上传类型" label-width="70">
              <ac-buttons
                v-model="buttonData.tplType"
                options="脚本,自定义"
                @change="changeTplType"
              />
            </el-form-item>
          </el-col>
          <el-col :span="5" v-if="buttonData.type === '下载'">
            <el-form-item label="下载类型" label-width="70">
              <ac-buttons
                v-model="buttonData.tplType"
                options="脚本,自定义"
                @change="changeTplType"
              />
            </el-form-item>
          </el-col>
          <el-col :span="5" v-if="buttonData.type === '下载模板'">
            <el-form-item label="模板类型" label-width="70">
              <ac-buttons
                v-model="buttonData.tplType"
                options="模板,自定义"
                @change="changeTplType"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6" v-if="buttonData.type === '下载模板' || (buttonData.type === '上传' && buttonData.tplType === '自定义')">
            <el-form-item label="模板名称" label-width="100">
              <el-input v-model="buttonData.tplName" />
            </el-form-item>
          </el-col>
          <el-col :span="6" v-if="buttonData.type === '下载模板' && buttonData.tplType === '模板'">
            <el-form-item label="模板" label-width="100">
              <ac-tree
                v-model="buttonData.tplFileId"
                data-url="/system/template/queryTree"
                type-select="template"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6" v-if="(buttonData.type === '上传' || buttonData.type === '下载') && buttonData.tplType==='脚本'">
            <el-form-item label="提交执行脚本" label-width="120">
              <template #label>
                <span style="margin-right: 5px">提交执行脚本</span>
                <el-tooltip>
                  <template #content>
                    <div>脚本接收参数：</div>
                    <div>1、dataList: 表格勾选的数据。</div>
                    <div>2、当为上传时，importList: 导入的excel数据</div>
                  </template>
                  <ac-icon iconId="018dca8ec9890493be26" />
                </el-tooltip>
              </template>
              <ac-tree
                v-model="buttonData.executeScriptId"
                data-url="/system/scriptGroovy/queryTree"
                type-select="script"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6" v-if="buttonData.tplType === '自定义'">
            <el-form-item label="数据模型" label-width="100">
              <ac-tree
                v-model="buttonData.modelId"
                data-url="/system/dataModel/queryTree"
                type-select="model"
                @change="initButtonField"
              />
            </el-form-item>
          </el-col>
          <el-col :span="6" v-if="buttonData.tplType === '自定义'">
            <div style="margin-left: 30px">
              <el-button
                v-if="sortFieldInst"
                type="info"
                @click="unSortDataField"
              >关闭排序</el-button>
              <el-button
                v-else-if="(buttonData.fieldList || []).length > 1"
                type="primary"
                @click="sortDataField"
              >开启排序</el-button>
            </div>
          </el-col>
        </el-row>
        <el-table
          v-if="buttonData.tplType === '自定义'"
          ref="sortFieldTable"
          :show-overflow-tooltip="false"
          tooltip-effect="light"
          class="field-table fit-table edit-table"
          width="100%"
          height="350px"
          :data="buttonData.fieldList"
          row-key="id"
          :border="true"
          :stripe="false"
          @cell-click="cellClick"
        >
          <el-table-column
            header-align="center"
            align="center"
            label="字段名称"
            :min-width="120"
            prop="fieldName"
          />
          <el-table-column
            header-align="center"
            align="center"
            label="显示名称"
            :min-width="120"
            prop="name"
          >
            <template #default="scope">
              <el-input v-model="scope.row.name" :disabled="scope.row.show !== '1'"/>
            </template>
          </el-table-column>
          <el-table-column
            v-if="buttonData.type === '下载' || buttonData.type === '下载模板'"
            header-align="center"
            label="列宽"
            :min-width="80"
            prop="width"
          >
            <template #default="scope">
              <ac-number v-model="scope.row.width" :point="0" />
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            align="center"
            :label="'是否' + buttonData.type"
            width="100"
            prop="show"
          >
            <template #default="scope">
              <ac-dict-switch v-model="scope.row.show" dictCode="dictYesNo" />
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-form>
    <template #footer>
      <el-button
        size="default"
        type="info"
        @click="buttonVisible=false"
      >取消</el-button>
      <el-button
        type="primary"
        size="default"
        @click="submitButtonForm"
      >确定</el-button>
    </template>
  </el-dialog>

  <!-- 查询编辑 -->
  <el-dialog
    v-model="filterVisible"
    width="600px"
    :title="filterTitle"
    :close-on-click-modal="false"
    destroy-on-close
    append-to-body
    draggable
  >
    <el-form
      ref="filterForm"
      label-width="120px"
      label-position="right"
      :model="filterData"
      :rules="filterRules"
    >
      <el-row>
        <el-col :span="24">
          <el-form-item label="名称" prop="name">
            <el-input v-model="filterData.name" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="类型" prop="type">
            <ac-select
              v-model="filterData.type"
              options="输入框,下拉框,单选框,按钮组,日期控件,树形控件"
              @change="changeFilterType"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="查询字段" prop="fieldIds">
            <ac-selects
              v-if="filterData.type === '输入框'"
              v-model="filterData.fieldIds"
              filterable
              :options="dataFieldOptions"
              @change="changeFilterFieldIds"
            />
            <ac-select
              v-else
              v-model="filterData.fieldIds"
              :options="dataFieldOptions"
              @change="changeFilterFieldIds"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="占位信息" prop="placeholder">
            <el-input v-model="filterData.placeholder" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="查询类型">
            <ac-select
              v-model="filterData.queryType"
              options="大于,大于等于,等于,小于,小于等于,不等于,包含,模糊"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="默认值" prop="defaultValue">
            <component
              v-if="filterData.fieldIds === '' || (filterData.fieldIds || '').indexOf(',') === -1"
              v-model="filterData.defaultValue"
              :is="getComponent(filterData.fieldIds, true) || 'ac-input'"
              v-bind="getOptions(filterData.fieldIds, true)"
            />
            <el-input v-else v-model="filterData.defaultValue" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <el-button
        size="default"
        type="info"
        @click="filterVisible=false"
      >取消</el-button>
      <el-button
        type="primary"
        size="default"
        @click="submitFilterForm"
      >确定</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue';
import api from "@/http/api";
import { ElMessage, ElMessageBox } from "element-plus";
import Sortable from 'sortablejs';
import tool from "@/utils/tool";
import loading from "@/utils/loading";

const emit = defineEmits(['afterSubmit'])
const props = defineProps({
  options: {
    type: Object,
    default: () => {}
  },
  pageParamList: Array
});

const formData = ref({});
const dataForm = ref();
const rules = ref({
  name: [
    {required: true, message: '请输入名称', trigger: ['change', 'blur']},
    {max: 100, message: '长度必须小于等于 200 个字符！', trigger: ['change', 'blur']}
  ],
});

const dataTableOptions = ref([]);
const dataFormOptions = ref([]);
const dataFieldOptions = ref([]);
const dataFieldNameOptions = ref([]);
const compParamOptions = ref([]);
const treeDataFieldOptions = ref([]);
const treeDataFormOptions = ref([]);
const middleFieldOptions = ref([]);

const fieldList = ref([]);
const buttonList = ref([]);
const currPageParamList = ref([]);
const selectButtonIds = ref([]);

const sortRadioGroup = ref();
const sortableInst = ref(null);
const sortFilterRadioGroup = ref();
const sortableFilterInst = ref(null);

const buttonVisible = ref(false);
const buttonTitle = ref('');
const buttonForm = ref();
const buttonRules = ref({
  name: [
    {required: true, message: '请输入名称', trigger: ['change', 'blur']},
    {max: 100, message: '长度必须小于等于 20 个字符！', trigger: ['change', 'blur']}
  ],
  type: [
    {required: true, message: '请选择类型', trigger: ['change', 'blur']},
  ],
});
const buttonData = ref({});
const predefineColors = ref([
  '#409EFF',
  '#67C23A',
  '#E6A23C',
  '#F56C6C',
  '#909399',
  '#ff4500',
  '#ff8c00',
  '#ffd700',
  '#90ee90',
  '#00ced1',
  '#1e90ff',
  '#c71585',
  '#FF7800',
]);
const sortFieldTable = ref();
const sortFieldInst = ref();
const sortingId = ref('');

const filterVisible = ref(false);
const filterTitle = ref('');
const filterForm = ref();
const filterRules = ref({
  name: [
    {required: true, message: '请输入名称', trigger: ['change', 'blur']},
    {max: 100, message: '长度必须小于等于 20 个字符！', trigger: ['change', 'blur']}
  ],
  type: [
    {required: true, message: '请选择类型', trigger: ['change', 'blur']},
  ],
});
const filterData = ref({queryType: ''});
const rowFlag = ref(0);

const init = async(options) => {
  loading.showLoading();
  selectButtonIds.value = [];

  await loadPageButton();
  await initFormData(options || {});
  await loadPageParamList(formData.value.pageId);
  await changeDataModel();
  await changeTreeDataModel();
  await changeMiddleDataModel();
  loading.hideLoading();
};

const initFormData = async(param) => {
  let data = param || {};
  if (!data.editing && param.id) {
    const res = await api.post('/system/pageComp/queryBy', {id: param.id});
    data = res.data || {};
  }
  const bList = data.buttonList || [];
  bList.forEach(button => {
    button.rowFlag = ++rowFlag.value;
    if (button.buttonId) {
      selectButtonIds.value.push(button.buttonId);
      const find = buttonList.value.find(item => item.id === button.buttonId);
      if (find) {
        button.name = find.showName;
      }
    }
  });
  data.buttonList = bList;

  const fList = data.filterList || [];
  fList.forEach(filter => {
    filter.rowFlag = ++rowFlag.value;
  });
  data.filterList = fList;
  data.editing = true;
  formData.value = data;
};

const changeDataModel = async() => {
  dataTableOptions.value = [];
  dataFormOptions.value = [];
  dataFieldOptions.value = [];
  dataFieldNameOptions.value = [];
  compParamOptions.value = [];

  if (formData.value.type !== '页面') {
    formData.value.dataPageId = '';
  } else {
    formData.value.dataModelId = '';
  }

  if (formData.value.type === '流程页面') {
    compParamOptions.value.push({key: 'instNodeId', value: '流程实例id'});
  }

  if (formData.value.dataPageId) {
    const pageParamList = await loadPageParam(formData.value.dataPageId);
    pageParamList.forEach(param => {
      compParamOptions.value.push({key: param.id, value: param.name});
    });
  }

  if (currPageParamList.value) {
    currPageParamList.value.forEach(param => {
      dataFieldNameOptions.value.push({key: param.id, value: '[全局]' + param.name});
    });
  }

  if (formData.value.dataModelId) {
    const tableList = await loadDataTable(formData.value.dataModelId);
    tableList.forEach(table => {
      dataTableOptions.value.push({key: table.id, value: table.name});
    });

    const formList = await loadDataForm(formData.value.dataModelId);
    formList.forEach(form => {
      dataFormOptions.value.push({key: form.id, value: form.name});
    });

    fieldList.value = await loadDataField(formData.value.dataModelId);
    fieldList.value.forEach(field => {
      compParamOptions.value.push({key: field.id, value: field.showName, label: field.showName});
      dataFieldOptions.value.push({key: field.id, value: field.showName, label: field.showName});
      dataFieldNameOptions.value.push({key: field.fieldName, value: field.showName});
    });
  }
};

const changeTreeDataModel = async() => {
  treeDataFormOptions.value = [];
  treeDataFieldOptions.value = [];

  if (!formData.value.treeDataModelId) {
    return;
  }

  const formList = await loadDataForm(formData.value.treeDataModelId);
  formList.forEach(form => {
    treeDataFormOptions.value.push({key: form.id, value: form.name});
  });

  const fieldList = await loadDataField(formData.value.treeDataModelId);
  fieldList.forEach(field => {
    treeDataFieldOptions.value.push({key: field.id, value: field.showName});
  });
};

const changeMiddleDataModel = async() => {
  middleFieldOptions.value = [];

  if (!formData.value.middleModelId) {
    return;
  }

  const fieldList = await loadDataField(formData.value.middleModelId);
  fieldList.forEach(field => {
    middleFieldOptions.value.push({key: field.id, value: field.showName});
  });
};

const loadPageParam = async(pageId) => {
  const res = await api.post('/system/pageParam/queryList', {pageId: pageId});
  return res.data || [];
};

const loadDataTable = async(modelId) => {
  const res = await api.post('/system/dataTable/queryList', {modelId: modelId});
  return res.data || [];
};

const loadDataForm = async(modelId) => {
  const res = await api.post('/system/dataForm/queryList', {modelId: modelId});
  return res.data || [];
};

const loadDataField = async(modelId) => {
  const res = await api.post('/system/dataField/queryList', {modelId: modelId});
  return res.data || [];
};

const loadPageButton = async() => {
  const res = await api.post('/system/pageButton/queryList');
  buttonList.value = res.data || [];
};

const loadPageParamList = async(pageId) => {
  if (props.pageParamList) {
    currPageParamList.value = props.pageParamList;
  } else {
    currPageParamList.value = await loadPageParam(pageId);
  }
};

const addPrivilege = () => {
  if (!formData.value.privilegeList) {
    formData.value.privilegeList = [];
  }

  formData.value.privilegeList.push({
    roleId: '',
    rowFlag: ++rowFlag.value,
    conditionList: [{}]
  });
};

const deletePrivilege = (privilege) => {
  ElMessageBox.confirm('请确认是否删除？', '提示', {type: 'warning'}).then(() => {
    const index = formData.value.privilegeList
      .findIndex(item => privilege.id ? item.id === privilege.id : item.rowFlag === privilege.rowFlag);
    formData.value.privilegeList.splice(index, 1);
  });
};

const addPrivilegeCondition = (privilege) => {
  privilege.conditionList.push({rowFlag: ++rowFlag.value});
};

const deletePrivilegeCondition = (privilege, data) => {
  ElMessageBox.confirm('请确认是否删除？', '提示', {type: 'warning'}).then(() => {
    const index = privilege.conditionList
      .findIndex(item => item.id ? item.id === data.id : item.rowFlag === data.rowFlag);
    privilege.conditionList.splice(index, 1);
  });
};

const getPrivilegeRowKey = row => {
  return row.id || row.rowFlag;
};

const privilegeRefs  = ref([]);
const setRefs = (el, privilege) => {
  if (el) {
    privilegeRefs.value['privilegeTable_' + (privilege.id || privilege.rowFlag)] = el;
  }
};

const sortPrivilegeField = (privilege) => {
  if (sortableInst.value) {
    sortableInst.value.destroy();
  }

  const ref = privilegeRefs.value['privilegeTable_' + (privilege.id || privilege.rowFlag)];
  if (ref) {
    const el = ref.$el.querySelector(".el-table__body-wrapper tbody");
    sortableInst.value = Sortable.create(el, {
      handle: '.el-table__row',
      onEnd: ({ newIndex, oldIndex}) => {
        const list = tool.deepClone(privilege.conditionList);
        const currRow = list.splice(oldIndex, 1)[0];
        list.splice(newIndex, 0, currRow);
        nextTick(() => {
          privilege.conditionList = list;
        });
      }
    });
    sortingId.value = privilege.id || privilege.rowFlag;
  }
};

const unSortPrivilegeField = () => {
  if (sortableInst.value) {
    sortableInst.value.destroy();
  }
  sortableInst.value = null;
};

const getParamRowKey = (row) => {
  return row.id || row.rowFlag;
};

const addCompParam = () => {
  if (!formData.value.paramList) {
    formData.value.paramList = [];
  }

  formData.value.paramList.push({rowFlag: ++rowFlag.value});
};

const deleteCompParam = (data) => {
  ElMessageBox.confirm('请确认是否删除？', '提示', {type: 'warning'}).then(() => {
    const index = formData.value.paramList
      .findIndex(item => item.id ? item.id === data.id : item.rowFlag === data.rowFlag);
    formData.value.paramList.splice(index, 1);
  }).catch(() => {});
};

const sortParamIndexInst = ref(null);
const sortParamTable = ref();
const sortParamIndex = () => {
  if (sortParamIndexInst.value) {
    sortParamIndexInst.value.destroy();
  }

  if (sortParamTable.value) {
    const el = sortParamTable.value.$el.querySelector(".el-table__body-wrapper tbody");
    sortParamIndexInst.value = Sortable.create(el, {
      handle: '.el-table__row',
      onEnd: ({ newIndex, oldIndex}) => {
        const list = tool.deepClone(formData.value.paramList);
        const currRow = list.splice(oldIndex, 1)[0];
        list.splice(newIndex, 0, currRow);
        nextTick(() => {
          formData.value.paramList = list;
        });
      }
    });
  }
};

const unSortParamIndex = () => {
  if (sortParamIndexInst.value) {
    sortParamIndexInst.value.destroy();
  }
  sortParamIndexInst.value = null;
};

const changeSelectButton = () => {
  selectButtonIds.value.forEach(id => {
    const find = formData.value.buttonList.find(item => item.buttonId && item.buttonId === id);
    if (!find) {
      const button = buttonList.value.find(item => item.id === id);
      if (button) {
        formData.value.buttonList.push({
          buttonId: button.id,
          name: button.name,
          showPosition: button.showPosition,
          dialogWidth: 800,
          rowFlag: ++rowFlag.value
        });
      }
    }
  });

  formData.value.buttonList.filter(item => item.buttonId).forEach(item => {
    const find = selectButtonIds.value.find(id => id === item.buttonId);
    if (!find) {
      const index = formData.value.buttonList.findIndex(index => index.rowFlag === item.rowFlag);
      formData.value.buttonList.splice(index, 1);
    }
  });
};

const deleteSelectedButton = (button) => {
  ElMessageBox.confirm('请确认是否删除【' + button.name + '】？', '提示', {type: 'warning'}).then(() => {
    const index = formData.value.buttonList.findIndex(item => item.rowFlag === button.rowFlag);
    formData.value.buttonList.splice(index, 1);

    const selectIndex = selectButtonIds.value.findIndex(id => id === button.buttonId);
    if (selectIndex >= 0) {
      selectButtonIds.value.splice(selectIndex, 1);
    }
  }).catch(() => {});
};

const editButton = (button) => {
  if (button) {
    buttonData.value = tool.deepClone(button);
    buttonTitle.value = '编辑按钮【' + button.name + '】';
    initButtonField();
  } else {
    buttonData.value = {
      dataVolume: '不限',
      showPosition: '顶部',
      fontColor: '#ffffff',
      backgroundColor: '#409eff',
      borderColor: '#409eff',
      rowFlag: ++rowFlag.value,
      fieldList: []
    };
    buttonTitle.value = '新增按钮';
  }

  if (buttonData.value.pageFieldJson) {
    buttonData.value.paramList = JSON.parse(buttonData.value.pageFieldJson);
  }
  changePage();
  buttonVisible.value = true;
};

const changeType = () => {
  buttonData.value.iconId = '';
  buttonData.value.backgroundColor = '#409eff';
  buttonData.value.borderColor = '#409eff';
  buttonData.value.submitValidate = '0';
  buttonData.value.showPosition = '顶部';
  buttonData.value.submitPrompt = '';
  buttonData.value.dataVolume = '不限';
  buttonData.value.endRefresh = '';
  buttonData.value.showCloseButton = '';
  buttonData.value.modelId = '';
  buttonData.value.fieldsJson = '';
  buttonData.value.dialogWidth = '';
  buttonData.value.fieldList = [];

  if (buttonData.value.type === '新增') {
    buttonData.value.name = buttonData.value.name ? buttonData.value.name : '新增';
    buttonData.value.dataVolume = '不限';
    buttonData.value.submitValidate = '1';
    buttonData.value.iconId = '018dc9c3efed46e8b927';
    buttonData.value.backgroundColor = '#67C23AFF';
    buttonData.value.borderColor = '#67C23AFF';
    buttonData.value.showPosition = '顶部';
    buttonData.value.dialogWidth = 800;
  } else if(buttonData.value.type === '编辑') {
    buttonData.value.name = buttonData.value.name ? buttonData.value.name : '编辑';
    buttonData.value.dataVolume = '单条';
    buttonData.value.iconId = '018dca6db20c6a3aaf68';
    buttonData.value.submitValidate = '1';
    buttonData.value.showPosition = '行内';
    buttonData.value.dialogWidth = 800;
  } else if(buttonData.value.type === '批量编辑') {
    buttonData.value.name = buttonData.value.name ? buttonData.value.name : '批量编辑';
    buttonData.value.dataVolume = '多条';
    buttonData.value.iconId = '018dca6db20c6a3aaf68';
    buttonData.value.submitValidate = '1';
    buttonData.value.dialogWidth = 800;
  } else if(buttonData.value.type === '上传') {
    buttonData.value.iconId = '018ece4f70fcf0627f81';
    buttonData.value.tplType = '脚本';
  } else if(buttonData.value.type === '下载') {
    buttonData.value.iconId = '018ece4f749ec5911772';
    buttonData.value.tplType = '脚本';
  } else if(buttonData.value.type === '下载模板') {
    buttonData.value.iconId = '018ece4f73a3ccb1ca1d';
    buttonData.value.tplType = '模板';
  } else if(buttonData.value.type === '弹出页面') {
    buttonData.value.iconId = '018ece4f758f70a05ff5';
    buttonData.value.endRefresh = '0';
    buttonData.value.showCloseButton = '1';
    buttonData.value.dialogWidth = 800;
  } else if(buttonData.value.type === '调用脚本') {
    buttonData.value.iconId = '018ece4f6a7ab5929bbe';
    buttonData.value.endRefresh = '1';
  } else if(buttonData.value.type === '删除') {
    buttonData.value.name = buttonData.value.name ? buttonData.value.name : '删除';
    buttonData.value.submitPrompt = '请确认是否删除？';
    buttonData.value.dataVolume = '多条';
    buttonData.value.iconId = '018dc9c3efd3a0502886';
    buttonData.value.backgroundColor = '#F56C6CFF';
    buttonData.value.borderColor = '#F56C6CFF';
    buttonData.value.showPosition = '顶部,行内';
  } else if(buttonData.value.type === '提交数据') {
    buttonData.value.name = buttonData.value.name ? buttonData.value.name : '提交数据';
    buttonData.value.submitPrompt = '请确认是否提交数据？';
    buttonData.value.dataVolume = '单条';
    buttonData.value.iconId = '018ece4f68eaa77e4813';
  }
};

const changeTplType = () => {
  if (buttonData.value.tplType === '自定义') {
    buttonData.value.modelId = formData.value.dataModelId;
    initButtonField();
  } else {
    buttonData.value.modelId = '';
  }
};

const initButtonField = () => {
  buttonData.value.fieldList = [];
  if (buttonData.value.modelId) {
    api.post('/business/data-field/list/' + buttonData.value.modelId).then(res => {
      let fieldList = [];
      if (buttonData.value && buttonData.value.fieldsJson) {
        fieldList = JSON.parse(buttonData.value && buttonData.value.fieldsJson || '[]');
        fieldList.forEach(field => field.show = '1');
      }
      res.data.forEach(field => {
        if (fieldList.every(item => item.id !== field.id)) {
          fieldList.push({id: field.id, name: field.showName, fieldName: field.fieldName, width: 15, show: '0'});
        }
      });
      buttonData.value.fieldList = fieldList;
    });
  }
};

const sortDataField = () => {
  if (sortFieldInst.value) {
    sortFieldInst.value.destroy();
  }

  if (sortFieldTable.value) {
    const el = sortFieldTable.value.$el.querySelector(".el-table__body-wrapper tbody");
    sortFieldInst.value = Sortable.create(el, {
      handle: '.el-table__row',
      onEnd: ({ newIndex, oldIndex}) => {
        const list = tool.deepClone(buttonData.value.fieldList);
        const currRow = list.splice(oldIndex, 1)[0];
        list.splice(newIndex, 0, currRow);
        nextTick(() => {
          buttonData.value.fieldList = list;
        });
      }
    });
  }
};

const unSortDataField = () => {
  if (sortFieldInst.value) {
    sortFieldInst.value.destroy();
  }
  sortFieldInst.value = null;
};

const submitButtonForm = () => {
  if (buttonData.value.dialogPageId && buttonData.value.paramList) {
    buttonData.value.pageFieldJson = JSON.stringify(
      buttonData.value.paramList.map(param => ({
        fieldName: param.fieldName,
        pageParamId: param.pageParamId,
        pageParamName: param.pageParamName
      })));
  } else {
    buttonData.value.pageFieldJson = '';
  }

  buttonForm.value && buttonForm.value.validate(valid => {
    if (valid) {
      if (!buttonData.value.buttonId
        && buttonData.value.tplType === '自定义'
        && (buttonData.value.type === '上传'
          || buttonData.value.type === '下载'
          || buttonData.value.type === '下载模板')) {
        buttonData.value.fieldsJson = JSON.stringify(buttonData.value.fieldList.filter(field => field.show === '1'));
      } else {
        buttonData.value.fieldsJson = null;
      }
      const index = formData.value.buttonList.findIndex(item => item.rowFlag === buttonData.value.rowFlag);
      if (index >= 0) {
        formData.value.buttonList[index] = buttonData.value;
      } else {
        formData.value.buttonList.push(buttonData.value);
      }

      buttonVisible.value = false;
    }
  });
};

const addUpdate = () => {
  if (!buttonData.value.updateList) {
    buttonData.value.updateList = [];
  }
  buttonData.value.updateList.push({rowFlag: ++rowFlag.value});
};

const deleteUpdate = (data) => {
  ElMessageBox.confirm('请确认是否删除？', '提示', {type: 'warning'}).then(() => {
    const index = buttonData.value.updateList
      .findIndex(item => item.id ? item.id === data.id : item.rowFlag === data.rowFlag);
    buttonData.value.updateList.splice(index, 1);
  }).catch(() => {});
};

const addCondition = () => {
  if (!buttonData.value.conditionList) {
    buttonData.value.conditionList = [];
  }
  buttonData.value.conditionList.push({rowFlag: ++rowFlag.value});
};

const deleteCondition = (data) => {
  ElMessageBox.confirm('请确认是否删除？', '提示', {type: 'warning'}).then(() => {
    const index = buttonData.value.conditionList
      .findIndex(item => item.id ? item.id === data.id : item.rowFlag === data.rowFlag);
    buttonData.value.conditionList.splice(index, 1);
  }).catch(() => {});
};

const editFilter = (filter) => {
  if (filter) {
    filterData.value = tool.deepClone(filter);
    filterTitle.value = '编辑查询';
  } else {
    filterData.value = {
      type: '输入框',
      queryType: '模糊',
      rowFlag: ++rowFlag.value
    };
    filterTitle.value = '新增查询';
  }
  filterVisible.value = true;
};

const deleteFilter = (filter) => {
  ElMessageBox.confirm('请确认是否删除？', '提示', {type: 'warning'}).then(() => {
    const index = formData.value.filterList.findIndex(item => item.rowFlag === filter.rowFlag);
    formData.value.filterList.splice(index, 1);
  }).catch(() => {});
};

const changeFilterType = () => {
  if ('下拉框,单选框,按钮组,日期控件,树形控件'.indexOf(filterData.value.type) >= 0) {
    filterData.value.queryType = '等于';
  } else if ('输入框'.indexOf(filterData.value.type) >= 0) {
    filterData.value.queryType = '模糊';
  }
};

const changeFilterFieldIds = () => {
  const fieldIds = (filterData.value.fieldIds || '').split(',');
  let fieldNames = '';
  fieldIds.forEach(id => {
    const option = dataFieldOptions.value.find(item => item.key === id);
    if (option) {
      if (fieldNames) {
        fieldNames += ',';
      }
      fieldNames += option.label;
    }
  });
  filterData.value.placeholder = fieldNames;
  if (!filterData.value.name) {
    filterData.value.name = fieldNames.split(',')[0];
  }
};

const submitFilterForm = () => {
  if (!formData.value.filterList) {
    formData.value.filterList = formData.value.filterList || [];
  }

  filterForm.value && filterForm.value.validate(valid => {
    if (valid) {
      if (!filterData.value.name.trim()) {
        ElMessage.error("名称不能为空！");
        return;
      }
      const index = formData.value.filterList.findIndex(item => item.rowFlag === filterData.value.rowFlag);
      if (index >= 0) {
        formData.value.filterList[index] = filterData.value;
      } else {
        formData.value.filterList.push(filterData.value);
      }

      filterVisible.value = false;
      filterData.value = {};
    }
  });
};

const sortButtonList = () => {
  if (sortableInst.value) {
    sortableInst.value.destroy();
  }

  if (sortRadioGroup.value) {
    const el = sortRadioGroup.value;
    sortableInst.value = Sortable.create(el, {
      handle: '.sort-item',
      onEnd: ({ newIndex, oldIndex}) => {
        const list = tool.deepClone(formData.value.buttonList);
        const currRow = list.splice(oldIndex, 1)[0];
        list.splice(newIndex, 0, currRow);
        nextTick(() => {
          formData.value.buttonList = list;
        });
      }
    });
  }
};

const closeButtonList = () => {
  if (sortableInst.value) {
    sortableInst.value.destroy();
    sortableInst.value = null;
  }
};

const changePage = () => {
  if (!buttonData.value.dialogPageId) {
    buttonData.value.paramList = [];
    return;
  }

  api.post('/system/pageParam/queryList', {pageId: buttonData.value.dialogPageId}).then(res => {
    const pageParamList = res.data || [];
    let paramList = buttonData.value.paramList || [];
    pageParamList.forEach(pageParam => {
      const fieldParam = paramList.find(item => item.pageParamId === pageParam.id);
      if (fieldParam) {
        fieldParam.pageParamName = pageParam.name;
      } else {
        paramList.push({pageParamId: pageParam.id, pageParamName: pageParam.name});
      }
    });

    paramList = paramList.filter(param => pageParamList.find(item => item.id === param.pageParamId));
    buttonData.value.paramList = paramList;
  });
};

const cellClick = async(row, column) => {
  if (column.property === 'fieldName') {
    row.show = row.show === '1' ? '0' : '1';
  }
}

const sortFilterList = () => {
  if (sortableFilterInst.value) {
    sortableFilterInst.value.destroy();
  }

  if (sortFilterRadioGroup.value) {
    const el = sortFilterRadioGroup.value;
    sortableFilterInst.value = Sortable.create(el, {
      handle: '.sort-item',
      onEnd: ({ newIndex, oldIndex}) => {
        const list = tool.deepClone(formData.value.filterList);
        const currRow = list.splice(oldIndex, 1)[0];
        list.splice(newIndex, 0, currRow);
        nextTick(() => {
          formData.value.filterList = list;
        });
      }
    });
  }
};

const closeFilterList = () => {
  if (sortableFilterInst.value) {
    sortableFilterInst.value.destroy();
    sortableFilterInst.value = null;
  }
};

const validate = (callback) => {
  dataForm.value && dataForm.value.validate(callback);
};

const getData = () => {
  return formData.value;
};

const submitData = () => {
  dataForm.value && dataForm.value.validate((valid) => {
    if (valid) {
      ElMessageBox.confirm("请确认是否提交？", "提示", { type: "info" }).then(() => {
        loading.showLoading();
        api.post('/system/pageComp/save', formData.value).then(res => {
          ElMessage.success(res.message);
          emit('afterSubmit')
          loading.hideLoading();
        }).catch(() => loading.hideLoading());
      }).catch(() => {});
    }
  });
};

const component = ref({
  '单行文本框': 'ac-input',
  '密码文本框': 'ac-password',
  '多行文本框': 'ac-input',
  '富文本框': 'ac-rich-editor',
  '单选框': 'ac-select',
  '下拉框': 'ac-select',
  '开关': 'ac-switch',
  '字符': 'ac-input',
  '整数': 'ac-number',
  '小数': 'ac-number',
  '日期': 'ac-date',
  '时间': 'ac-datetime',
  '图片': 'ac-image',
  '视频': 'ac-video',
  '附件': 'ac-affix',
  '下拉选择': 'ac-remote-select',
  '树形控件': 'ac-dm-tree',
  '区划树': 'ac-region-tree',
  '单位树': 'ac-unit-tree',
  '企业树': 'ac-entp-tree',
  '部门树': 'ac-organization-tree',
  '人员树': 'ac-employee-tree',
  '字典树': 'ac-dm-tree',
  '字典开关': 'ac-dict-switch',
  '字典单选框': 'ac-dict-select',
  '字典下拉框': 'ac-dict-select',
});
const getComponent = (fieldId, all) => {
  if (!fieldId) return;
  const field = fieldList.value.find(item => item.id === fieldId);
  if (!field) return 'ac-input';

  if (field.fieldType === '字符') {
    if (field.enumerate === '1') {
      return all ? 'ac-select' : component.value[field.enumerateType];
    } else {
      return component.value[field.inputType];
    }
  } else if ("整数、小数、日期、时间、图片、视频、附件".indexOf(field.fieldType) >= 0) {
    return component.value[field.fieldType];
  } else if (field.fieldType === '联动') {
    if (field.relevanceType === '数据模型') {
      return component.value['树形控件'];
    } else {
      return component.value[field.relevanceType];
    }
  } else if (field.fieldType === '大文本') {
    return component.value[field.inputType];
  }

  return 'ac-input';
};

const getCondComponent = (fieldId) => {
  if (!fieldId) return;
  const field = fieldList.value.find(item => item.id === fieldId);
  if (!field) return 'ac-input';

  if (field.fieldType === '字符') {
    if (field.enumerate === '1') {
      return component.value[field.enumerateType];
    } else {
      return component.value[field.inputType];
    }
  } else if ("整数、小数、日期、时间".indexOf(field.fieldType) >= 0) {
    return component.value[field.fieldType];
  } else if (field.fieldType === '联动') {
    if (field.relevanceType === '数据模型') {
      return component.value['树形控件'];
    } else {
      return component.value[field.relevanceType];
    }
  }

  return 'ac-input';
};

const getOptions = (fieldId) => {
  if (!fieldId) return;

  const field = fieldList.value.find(item => item.id === fieldId);
  if (!field) return {};

  if (field.fieldType === '字符') {
    if (field.autoCreate === '1') {
      return {};
    } else if (field.enumerate === '1') {
      return {options: field.enumerateValue || ''};
    } else {
      return {max: field.fieldSize || 100};
    }
  } else if ("整数、小数".indexOf(field.fieldType) >= 0) {
    return {
      point: "整数" === field.fieldType ? 0 : field.fieldPrecision || 0,
      max: field.maxValue, min: field.minValue
    };
  } else if ("日期".indexOf(field.fieldType) >= 0) {
    return {format: field.format || undefined, valueFormat: field.format || undefined};
  } else if (field.fieldType === '图片') {
    return {limit: 1, maxSize: field.imageMaxSize};
  } else if (field.fieldType === '视频') {
    return {limit: 1, maxSize: field.imageMaxSize};
  } else if (field.fieldType === '联动') {
    if (field.relevanceType === '数据模型') {
      const relevanceList = field.relevanceList || [];
      return {
        dataFieldId: field.id,
        leafSelect: relevanceList.length > 1,
        typeSelect: relevanceList[relevanceList.length - 1].id
      };
    } else {
      return {dictCode: field.relevanceDict || ''};
    }
  }

  return {};
};

watch(() => props.options, (options) => {
  init(tool.deepClone(options || {}));
}, {deep: true});

onMounted(() => {
  init(tool.deepClone(props.options || {}));
});

defineExpose({ validate, getData, submitData });
</script>

<style scoped lang="scss">
.section-tips {
  font-size: 15px;
  font-weight: 900;
  border-bottom: 1px solid #8c939d;
  display: inline-flex;
  align-items: end;
  height: 100%;
}
.sort-box {
  display: contents;
  .sort-item {
    padding: 0 15px;
    border: 1px solid #dcdfe6;
    border-radius: 5px;
    margin: 2px 8px 2px 0;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    :deep(.ac-icon) {
      margin-left: 8px;
      cursor: pointer;
    }
  }
  :deep(.el-button) {
    margin: 2px 8px 2px 0 ;
  }
}
.param-item {
  display: flex;
  flex-direction: row;
  .param-field {
    width: 175px;
  }
  .param-split {
    width: 44px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 20px;
  }
  .param-page {
    flex-grow: 1;
  }
}
.param-item+.param-item {
  margin-top: 5px;
}
</style>